﻿<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Openmp实现矩阵乘法</title>
  <link rel="stylesheet" href="https://stackedit.io/style.css" />
</head>

<body class="stackedit">
  <div class="stackedit__html"><h1 id="openmp实现矩阵乘法">Openmp实现矩阵乘法</h1>
<p><strong>计试61 张翀 2140506063</strong></p>
<h2 id="题目">题目</h2>
<p>Create a program that computes a simple matrix vector multiplication b=Ax, either in fortran or C/C++. Use OpenMP directives to make it run in parallel.</p>
<h2 id="思路">思路</h2>
<p>矩阵与列向量相乘，每一行和列向量的乘法是独立的，可以并行执行。</p>
<h2 id="代码">代码</h2>
<p>核心命令：<code>#pragma omp parallel for num_threads(num_threads)</code><br>
这条命令的含义是，紧跟代码的for循环被多个线程并行执行，线程数由参数<code>num_threads</code>确定。在两层for循环中，第一层的含义是各行依次乘以列向量，这个过程可以并行执行；第二层的含义是元素按对应位置相乘并累加完成矩阵求成绩，这个过程是串行过程。因此，应该并行第一层for循环。<br>
为方便测试时间，设计函数<code>matGene</code>生成指定大小的矩阵，<code>vecGene</code>生成指定大小的向量，生成矩阵之后求乘积，再输出结果。设计代码见附属文件。</p>
<h2 id="实验结果">实验结果</h2>
<p>使用如下命令编译并执行：<code>g++ -fopenmp main.cpp &amp;&amp; ./a.out mat_dim num_threads</code>，执行可执行文件时带的两个参数分别是矩阵维度和使用的线程数。<br>

<div class="stackedit__html"></div>

测试时间如下：</p>

<table>
<thead>
<tr>
<th align="center">线程数</th>
<th align="center">1</th>
<th align="center">2</th>
<th align="center">并行加速比</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">256</td>
<td align="center">0.0011235</td>
<td align="center">0.0004969</td>
<td align="center">2.2610</td>
</tr>
<tr>
<td align="center">512</td>
<td align="center">0.0009619</td>
<td align="center">0.000554</td>
<td align="center">1.7363</td>
</tr>
<tr>
<td align="center">1024</td>
<td align="center">0.0055994</td>
<td align="center">0.0036887</td>
<td align="center">1.5180</td>
</tr>
<tr>
<td align="center">2048</td>
<td align="center">0.0193594</td>
<td align="center">0.0102305</td>
<td align="center">1.8923</td>
</tr>
<tr>
<td align="center">4096</td>
<td align="center">0.0614695</td>
<td align="center">0.0358153</td>
<td align="center">1.7163</td>
</tr>
</tbody>
</table><p>表格中最左侧一栏为测试时矩阵维度，表格中时间单位为秒。</p>
<p><img alt="矩阵乘法并行时间展示" src="https://gitee.com/WinterShiver/HPC/raw/master/OpenMP/1-matrix-multi/1.png"></p>
<p>以上为程序运行时间的测试结果展示，为方便展示，横纵坐标均取对数。由图像可见两点：</p>
<ul>
<li>通过直线的大致斜率可见，矩阵乘法的算法是O(n^2)的；</li>
<li>通过2线程并行执行程序，程序确实能获得近似为2的加速比；</li>
<li>维度数较小时，测量误差较大超过2的加速比是测量误差所导致的。</li>
</ul>
</div>
</body>

</html>
